package com.ruoyi.web.controller.system;

import java.io.IOException;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.FileUtils;
import com.ruoyi.common.utils.LinuxCmdUtil;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.service.ISysConfigService;

/**
 * 参数配置 信息操作处理
 * 
 * @author ruoyi
 */
@Controller
@RequestMapping("/system/config")
public class SysConfigController extends BaseController
{
	private static final Logger log = LoggerFactory.getLogger(SysConfigController.class);
    private String prefix = "system/config";

    @Autowired
    private ISysConfigService configService;

    @RequiresPermissions("system:config:view")
    @GetMapping()
    public String config()
    {
        return prefix + "/config";
    }

    /**
     * 查询参数配置列表
     */
    @RequiresPermissions("system:config:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(SysConfig config)
    {
        startPage();
        List<SysConfig> list = configService.selectConfigList(config);
        return getDataTable(list);
    }

    @Log(title = "参数管理", businessType = BusinessType.EXPORT)
    @RequiresPermissions("system:config:export")
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(SysConfig config)
    {
        List<SysConfig> list = configService.selectConfigList(config);
        ExcelUtil<SysConfig> util = new ExcelUtil<SysConfig>(SysConfig.class);
        return util.exportExcel(list, "参数数据");
    }

    /**
     * 新增参数配置
     */
    @GetMapping("/add")
    public String add()
    {
        return prefix + "/add";
    }

    /**
     * 新增保存参数配置
     */
    @RequiresPermissions("system:config:add")
    @Log(title = "参数管理", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(@Validated SysConfig config)
    {
        if (!configService.checkConfigKeyUnique(config))
        {
            return error("新增参数'" + config.getConfigName() + "'失败，参数键名已存在");
        }
        config.setCreateBy(getLoginName());
        return toAjax(configService.insertConfig(config));
    }

    /**
     * 修改参数配置
     */
    @RequiresPermissions("system:config:edit")
    @GetMapping("/edit/{configId}")
    public String edit(@PathVariable("configId") Long configId, ModelMap mmap)
    {
        mmap.put("config", configService.selectConfigById(configId));
        return prefix + "/edit";
    }

    /**
     * 修改保存参数配置
     */
    @RequiresPermissions("system:config:edit")
    @Log(title = "参数管理", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(@Validated SysConfig config)
    {
        if (!configService.checkConfigKeyUnique(config))
        {
            return error("修改参数'" + config.getConfigName() + "'失败，参数键名已存在");
        }
        
        String configKey = config.getConfigKey();
        
        //修改机器IP的情况
        if(configKey.contains("age_ip")) {
        	
        	String oldIp = "";
        	String newIp = config.getConfigValue();
        	
        	try {
        		oldIp = configService.selectConfigById(config.getConfigId()).getConfigValue();
			} catch (Exception e) {
				// TODO: handle exception
				return error("修改参数'" + config.getConfigName() + "'失败，原因：" + e.getStackTrace());
			}
        	
        	//修改Prometheus配置文件
        	String promeConfigPath = "/home/hdsoft/prometheus-2.39.1.linux-arm64/prometheus.yml";
        	String command = "sed -i 's/" + oldIp + "/" + newIp + "/g' " + promeConfigPath;
        	AjaxResult excuteRsult = LinuxCmdUtil.exeLinux(command);
        	if(excuteRsult.isError()) {
        		return error("修改参数'" + config.getConfigName() + "'失败，原因："+excuteRsult.toString());
			}
        	
        	//重启Prometheus
        	String restartPromCommand = "systemctl restart prometheus_server.service";
        	AjaxResult excuteRestartPromRsult = LinuxCmdUtil.exeLinux(restartPromCommand);
        	if(excuteRestartPromRsult.isError()) {
        		return error("修改参数'" + config.getConfigName() + "'失败，原因："+excuteRestartPromRsult.toString());
			}
        	
        	
            //处理修改磁盘阵列IP时修改nginx配置
            if("storage_ip".equals(configKey)) {
            	
            	//修改NGINX配置
            	String nginxConfPath = "/etc/nginx/nginx.conf";
            	String nginxEditConfCommand = "sed -i 's/" + oldIp + "/" + newIp + "/g' " + nginxConfPath;
            	AjaxResult nginxEditRsult = LinuxCmdUtil.exeLinux(nginxEditConfCommand);
            	if(nginxEditRsult.isError()) {
            		return error("修改参数'" + config.getConfigName() + "'失败，原因："+nginxEditRsult.toString());
    			}
            	
            	//重启NGINX
            	String restartNginxCommand = "systemctl restart nginx.service";
            	AjaxResult excuteRestartNginxRsult = LinuxCmdUtil.exeLinux(restartNginxCommand);
            	if(excuteRestartNginxRsult.isError()) {
            		return error("修改参数'" + config.getConfigName() + "'失败，原因："+excuteRestartNginxRsult.toString());
    			}
            	
            }
        }
        
        //先更新，再复制
        config.setUpdateBy(getLoginName());
        int updateResult = configService.updateConfig(config);
        
        //修改配置时，将配置信息写入各个节点
        //目录：/etc/net_storage, 文件名称：usercfg.json
        SysConfig userCfg = new SysConfig();
		List<SysConfig> configList = configService.selectConfigList(userCfg);
		String jsonStr = JSONObject.toJSONString(configList);
    	String filePath = "/etc/net_storage/";
    	String fileName = "usercfg.json";
		//先写入本地
		try {
			FileUtils.bufferedWriterMethod(filePath+fileName, jsonStr);
		} catch (IOException e) {				
			//return error("修改参数'" + config.getConfigName() + "'失败，同步配置到各节点文件出错，原因：" + e.getMessage());
			log.error("修改参数【{}】失败，同步配置到各节点文件出错，原因：【{}】", config.getConfigName(), e);
		}
		//再分发至各节点
		for(SysConfig myConfig : configList) {
			if(myConfig.getConfigKey().contains("age_ip")) {
				String sendIp = myConfig.getConfigValue();
				String scpCommand = "scp " + filePath+fileName + " root@"+sendIp+":"+filePath;
   	        	AjaxResult scpRsult = LinuxCmdUtil.exeLinux(scpCommand);
   	        	if(scpRsult.isError()) {
   	        		log.error("复制文件到IP【{}】失败，原因【{}】", sendIp, scpRsult.toString());
   				}
			}
		}
        
        
        return toAjax(updateResult);
    }

    /**
     * 删除参数配置
     */
    @RequiresPermissions("system:config:remove")
    @Log(title = "参数管理", businessType = BusinessType.DELETE)
    @PostMapping("/remove")
    @ResponseBody
    public AjaxResult remove(String ids)
    {
        configService.deleteConfigByIds(ids);
        return success();
    }

    /**
     * 刷新参数缓存
     */
    @RequiresPermissions("system:config:remove")
    @Log(title = "参数管理", businessType = BusinessType.CLEAN)
    @GetMapping("/refreshCache")
    @ResponseBody
    public AjaxResult refreshCache()
    {
        configService.resetConfigCache();
        return success();
    }

    /**
     * 校验参数键名
     */
    @PostMapping("/checkConfigKeyUnique")
    @ResponseBody
    public boolean checkConfigKeyUnique(SysConfig config)
    {
        return configService.checkConfigKeyUnique(config);
    }
}
